﻿//-----------------------------------------------------------------------
//  This file is part of the Microsoft Code Samples.
// 
//  Copyright (C) Microsoft Corporation.  All rights reserved.
// 
//  This source code is intended only as a supplement to Microsoft
//  Development Tools and/or on-line documentation.  See these other
//  materials for detailed information regarding Microsoft code samples.
// 
//  THIS CODE AND INFORMATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//-----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Xml;
using System.Threading;
using System.Diagnostics;
using System.IO;

namespace RetailAnalytic.Tools.ActivitySystem
{
    /// <summary>
    /// Summary description for Utilities.
    /// </summary>
    public class Utilities : IDisposable
    {
        private const string LOG_ITEM_TEMPLATE_BEGIN
            = "Begin\t<ACTION>\t<TYPE>\t<VALUE>\t<SERVER><DATA>";
        private const string LOG_ITEM_TEMPLATE_END
            = "End\t<ACTION>\t<TYPE>\t<VALUE>\t<SERVER><DATA>";
        private const string LOG_ITEM_TEMPLATE_ERROR
            = "Error\t<ACTION>\t<TYPE>\t<VALUE>\t<SERVER>\t<DATA>";

        #region Member Variables
        private Dictionary<string, ASCommands> _servers
            = new Dictionary<string, ASCommands>();
        //private System.Diagnostics.TextWriterTraceListener activityTraceListener;
        #endregion

        #region Constructor / Destructor
        public Utilities()
        {
        }
        ~Utilities()
        {
            Dispose(false);
        }
        #endregion

        #region Public Methods

        /// <summary>
        /// Returns the list of Analysis Services Servers registered in the SQL Server Management Studio
        /// </summary>
        /// <returns></returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1302:DoNotHardcodeLocaleSpecificStrings"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
        //public static XmlNodeList GetServers()
        //{
        //    //get path to the Application Data folder for this user
        //    string sqlPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
        //    sqlPath += @"\Microsoft\Microsoft SQL Server\90\Tools\Shell\RegSrvr.xml";
        //    if (!System.IO.File.Exists(sqlPath))
        //    {
        //        throw new ApplicationException("Cannot locate registered servers.  Please make sure Analysis Servers have been registered in SQL Server Management Studio.");
        //    }

        //    XmlDocument xdoc = new XmlDocument();
        //    xdoc.Load(sqlPath);

        //    //locate the Analysis Services Servers/Groups
        //    XmlNodeList xnodeList = xdoc.SelectNodes("/RegisteredServers/ServerType[@name='Analysis Services']/*");
        //    if (xnodeList.Count == 0)
        //    {
        //        throw new ApplicationException("No registered servers found. Please register Analysis Services Servers in SQL Server Management Studio before using this application.");
        //    }

        //    return xnodeList;
        //}
        public static string GetServers()
        {
            return "CLEVER\\S2K5";
            //get path to the Application Data folder for this user
            //string sqlPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
            //sqlPath += @"\Microsoft\Microsoft SQL Server\90\Tools\Shell\RegSrvr.xml";
            //if (!System.IO.File.Exists(sqlPath))
            //{
            //    throw new ApplicationException("Cannot locate registered servers.  Please make sure Analysis Servers have been registered in SQL Server Management Studio.");
            //}

            //XmlDocument xdoc = new XmlDocument();
            //xdoc.Load(sqlPath);

            ////locate the Analysis Services Servers/Groups
            //XmlNodeList xnodeList = xdoc.SelectNodes("/RegisteredServers/ServerType[@name='Analysis Services']/*");
            //if (xnodeList.Count == 0)
            //{
            //    throw new ApplicationException("No registered servers found. Please register Analysis Services Servers in SQL Server Management Studio before using this application.");
            //}

           // return xnodeList;
        }

        public ASCommands GetValidASCommandObject(string serverName)
        {
            lock (_servers)
            {
                if (!_servers.ContainsKey(serverName))
                {
                    _servers.Add(serverName, new ASCommands(serverName));
                }

                return _servers[serverName];
            }
        }

        public static void SaveGridToFile(System.Windows.Forms.DataGridView dataGrid, string fieldDelimiter, string filePath)
        {
            //if we can force the column output to match the display order, then this 
            //method would be preferred over SaveDataTableToFile
            using (StreamWriter sw = new StreamWriter(filePath, false))
            {
                System.Text.StringBuilder sb
                    = new System.Text.StringBuilder(dataGrid.Columns.Count);
                for (int i = 0; i < dataGrid.Columns.Count; i++)
                {
                    sb.Append(dataGrid.Columns[i].Name + fieldDelimiter);
                }

                sw.WriteLine(sb.ToString());
                foreach (System.Windows.Forms.DataGridViewRow row in dataGrid.Rows)
                {
                    sb = new System.Text.StringBuilder(row.Cells.Count);
                    //we must iterate over each cell in order to check for null
                    //using the build in CopyTo into an array won't work with null values
                    for (int i = 0; i < row.Cells.Count; i++)
                    {
                        if (row.Cells[i].Value is DBNull)
                        {
                            sb.Append("(null)" + fieldDelimiter);
                        }
                        else
                        {
                            sb.Append(row.Cells[i].Value.ToString() + fieldDelimiter);
                        }
                    }

                    sw.WriteLine(sb.ToString());
                }
            }
        }

        public static void SaveDataTableToFile(System.Data.DataTable dataTable, string fieldDelimiter, string filePath)
        {
            using (StreamWriter sw = new StreamWriter(filePath, false))
            {
                System.Text.StringBuilder sb
                    = new System.Text.StringBuilder(dataTable.Columns.Count);
                for (int i = 0; i < dataTable.Columns.Count; i++)
                {
                    sb.Append(dataTable.Columns[i].ColumnName + fieldDelimiter);

                }

                sw.WriteLine(sb.ToString());
                foreach (System.Data.DataRow row in dataTable.Rows)
                {
                    sb = new System.Text.StringBuilder(dataTable.Columns.Count);
                    //we must iterate over each cell in order to check for null
                    //using the build in CopyTo into an array won't work with null values
                    for (int i = 0; i < dataTable.Columns.Count; i++)
                    {
                        if (row[i] is DBNull)
                        {
                            sb.Append("(null)" + fieldDelimiter);
                        }
                        else
                        {
                            sb.Append(row[i].ToString() + fieldDelimiter);
                        }
                    }

                    sw.WriteLine(sb.ToString());
                }
            }
        }
        #endregion

        #region IDisposable
        public void Dispose()
        {
            Dispose(true);
        }
        #endregion

        #region Private Methods
        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                GC.SuppressFinalize(this);
            }

            lock (_servers)
            {
                if (_servers != null && _servers.Count > 0)
                {
                    Dictionary<string, ASCommands>.ValueCollection values
                        = _servers.Values;
                    foreach (ASCommands obj in values)
                    {
                        obj.Dispose();
                    }

                    _servers.Clear();
                }
            }
        }
        #endregion

        #region Statics

        private static TraceSwitch activityTrace
            = new TraceSwitch("TraceActivity", "Task monitor activity tracing.");

        public static bool IsLoggingEnabled
        {
            get
            {
                if (activityTrace.Level >= TraceLevel.Off)
                {
                    return true;
                }

                return false;
            }
        }

        public static void LogActivityMessage(string message, TraceLevel level)
        {
            if (activityTrace.Level == TraceLevel.Off)
            {
                return;
            }

            if (activityTrace.Level >= level)
            {
                Trace.WriteLine(DateTime.Now.ToString() + "\t " + message);
            }
        }

        public static void LogActivityItemBegin(MonitoredItem item)
        {
            string message = LOG_ITEM_TEMPLATE_BEGIN.Replace("<ACTION>",
                item.ItemAction.ToString());
            message = message.Replace("<TYPE>", item.ItemType.ToString());
            message = message.Replace("<VALUE>", item.ItemValue.ToString());
            message = message.Replace("<SERVER>", item.ServerName);
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            foreach (string s in item.AdditionalData)
            {
                sb.Append("\t" + s);
            }

            message = message.Replace("<DATA>", sb.ToString());
            Utilities.LogActivityMessage(message, TraceLevel.Info);
        }

        public static void LogActivityItemEnd(MonitoredItem item)
        {
            string message = LOG_ITEM_TEMPLATE_END.Replace("<ACTION>",
                item.ItemAction.ToString());
            message = message.Replace("<TYPE>", item.ItemType.ToString());
            message = message.Replace("<VALUE>", item.ItemValue.ToString());
            message = message.Replace("<SERVER>", item.ServerName);
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            foreach (string s in item.AdditionalData)
            {
                sb.Append("\t" + s);
            }

            message = message.Replace("<DATA>", sb.ToString());
            Utilities.LogActivityMessage(message, TraceLevel.Info);
        }

        public static void LogActivityItemError(MonitoredItem item, string errorMessage)
        {
            string message = LOG_ITEM_TEMPLATE_ERROR.Replace("<ACTION>",
                item.ItemAction.ToString());
            message = message.Replace("<TYPE>", item.ItemType.ToString());
            message = message.Replace("<VALUE>", item.ItemValue.ToString());
            message = message.Replace("<SERVER>", item.ServerName);
            message = message.Replace("<DATA>", errorMessage);
            Utilities.LogActivityMessage(message, TraceLevel.Error);
        }

        #endregion
    }
}
